package com.smarttest.portal.controller;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletResponse;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.jcraft.jsch.Channel;
import com.jcraft.jsch.Session;
import com.smarttest.common.beans.JsonDataResult;
import com.smarttest.common.beans.PaginationResult;
import com.smarttest.common.beans.SFTPOPBean;
import com.smarttest.common.util.JsonUtils;
import com.smarttest.portal.pojo.DbAutoEnvironment;
import com.smarttest.portal.pojo.DbAutoInterfacescenedetailsWithBLOBs;
import com.smarttest.portal.pojo.DbAutoInterfacesummary;
import com.smarttest.portal.pojo.DbAutoInterfacesummaryWithBLOBs;
import com.smarttest.portal.pojo.DbAutoModule;
import com.smarttest.portal.service.Autocase_Mgmt_Service;
import com.smarttest.portal.service.Autocase_Mgmt_V2_Service;

@RequestMapping("/AutoInterface")
@Controller
public class AutoInterfaceController {
	private final Logger log = Logger.getLogger(getClass());
	@Autowired
	@Qualifier("infAuto")
	private Autocase_Mgmt_Service caseMgmtService;
	@Autowired
	private Autocase_Mgmt_V2_Service caseMgmtV2Service;

	@RequestMapping(value = "/search/table.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public PaginationResult searchTest(String name, String classes, String scenes, String owners, String searchvalue,
			int level, int pageSize, int toPage) {
		PaginationResult result = caseMgmtService.searchCase(name, classes, scenes, owners, searchvalue, level,
				pageSize, toPage);
		return result;
	}

	@RequestMapping(value = "/case/add.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult addTest(long id, String name, String clazz, String scenes, String owner, String remark,
			int level, String url) {
		int resultInt = 0;
		if (id > 0) {
			resultInt = caseMgmtService.updateCase(id, name, clazz, scenes, owner, remark, level, url);
		} else {
			resultInt = caseMgmtService.createCase(name, clazz, scenes, owner, remark, level, url);
		}
		if (resultInt > 0) {
			return JsonDataResult.ok();
		} else {
			return JsonDataResult.error(200);
		}
	}

	@RequestMapping(value = "/case/delete.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult deleteTest(String idsStr) {
		if (idsStr == null)
			return JsonDataResult.error(300);
		String[] idsarr = idsStr.split(",");
		if (idsarr.length <= 0) {
			return JsonDataResult.error(300);
		}
		List<Long> ids = new ArrayList<Long>();
		for (String each : idsarr) {
			ids.add(Long.parseLong(each));
		}
		int result = caseMgmtService.softDeleteCase(ids);
		return JsonDataResult.ok(result);
	}

	@RequestMapping(value = "/search/data.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public PaginationResult searchTest(int caseid, int envid, int level, String searchvalue, int pageSize, int toPage) {
		PaginationResult result = caseMgmtService.searchCaseData(caseid, level, searchvalue, pageSize, toPage);
		return result;
	}

	@RequestMapping(value = "/case/upload.action", method = RequestMethod.POST)
	@ResponseBody
	public String uploadCase(@RequestParam(value = "caseupload") MultipartFile caseupload) {
		Map result = caseMgmtService.uploadCase(caseupload);
		// 为了保证功能的兼容性，需要把Result转换成json格式的字符串。
		String json = JsonUtils.objectToJson(result);
		return json;
	}

	@RequestMapping(value = "/case/downloadsingle.action", method = { RequestMethod.GET })
	@ResponseBody
	public void exportMessage(String casedownLoadUrl, HttpServletResponse response) {
		System.out.println("----downloadcase---------start...");
		try {
			String name = casedownLoadUrl.substring(casedownLoadUrl.lastIndexOf("/") + 1, casedownLoadUrl.length());
			if (name == null || "".equals("name") || !name.contains(".jmx")) {
				return;
			}
			init(response, name);
			SFTPOPBean result = caseMgmtService.downLoadSingleCase(casedownLoadUrl);
			if (result == null) {
				return;
			}
			write(result, response);
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e);
		}
		System.out.println("-------exportCase-------finished");
	}

	@RequestMapping(value = "/getModuleByEnv.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult getModuleByEnv(Integer id) {
		List<DbAutoModule> resultModule = caseMgmtV2Service.getModuleByEnv(id);
		if (null != resultModule && resultModule.size() > 0) {
			return JsonDataResult.ok(resultModule);
		} else {
			return JsonDataResult.error(300);
		}
	}
	
	@RequestMapping(value = "/getInfByEnv.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult getInfByEnv(Integer id) {
		List<DbAutoInterfacesummary> resultModule = caseMgmtV2Service.getInfByEnv(id);
		if (null != resultModule && resultModule.size() > 0) {
			return JsonDataResult.ok(resultModule);
		} else {
			return JsonDataResult.error(300);
		}
	}

	@RequestMapping(value = "/initEnvSele.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult initEnvSele() {
		List<DbAutoEnvironment> resultModule = caseMgmtV2Service.initEnvSele();
		if (null != resultModule && resultModule.size() > 0) {
			return JsonDataResult.ok(resultModule);
		} else {
			return JsonDataResult.error(300);
		}
	}

	@RequestMapping(value = "/getInfByModule.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult getInfByModule(String idStr) {
		if (idStr == null) {
			return JsonDataResult.error(300);
		}
		List<Integer> ids = JSON.parseArray(idStr, Integer.class);
		if (null == ids || ids.size() < 1) {
			return JsonDataResult.error(300);
		}
		List<DbAutoInterfacesummary> resultInf = caseMgmtV2Service.getInfByModule(ids);
		if (null != resultInf) {
			return JsonDataResult.ok(resultInf);
		} else {
			return JsonDataResult.error(300);
		}
	}

	@RequestMapping(value = "/getInfBySearch.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult getInfBySearch(int env,String modules, String idStr, String importantsStr, String ownersStr, String levels) {
		List<Integer> ids = JSON.parseArray(idStr, Integer.class);
		List<Integer> importants = JSON.parseArray(importantsStr, Integer.class);
		List<String> owners = JSON.parseArray(ownersStr, String.class);
		List<Integer> modulelist = JSON.parseArray(modules, Integer.class);
		List<Integer> levellist = JSON.parseArray(levels, Integer.class);
		List<DbAutoInterfacesummaryWithBLOBs> resultInf = caseMgmtV2Service.getInfBySearch(env,modulelist, ids, importants, owners,levellist);
		if (null != resultInf) {
			return JsonDataResult.ok(resultInf);
		} else {
			return JsonDataResult.error(300);
		}
	}

	@RequestMapping(value = "/addAutoCase.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult addInterface(String inf, int env, int url, String inftype, int degree, int module,
			String tester, String reqType, String outerparams, boolean dataAsUrlparam, String inits, String dataitems) {
		int result = 0;
		if (null != dataitems) {
			List<DbAutoInterfacescenedetailsWithBLOBs> obj = (List<DbAutoInterfacescenedetailsWithBLOBs>) JSON.parseArray(dataitems, DbAutoInterfacescenedetailsWithBLOBs.class);
			if (obj.size() > 0) {
				try {
					result = caseMgmtV2Service.addAutoCase(inf, env, url, inftype, degree, module, tester, reqType,
							outerparams, dataAsUrlparam, inits,obj);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
		if (result > 0) {
			return JsonDataResult.ok();
		} else {
			return JsonDataResult.error(0);
		}
	}
	
	
	@RequestMapping(value = "/updateAutoCase.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult updateAutoCase(int id, String inf, int env, int url, String inftype, int degree, int module,
			String tester, String reqType, String outerparams, boolean dataAsUrlparam, String dataitems,String deleteidsStr) {
		int result = 0;
		String[] idsarr = deleteidsStr.split(",");
		List<Integer> ids = new ArrayList<Integer>();
		if(idsarr.length>0){
		  for (String each : idsarr) {
			if(!each.equals("")){
			ids.add(Integer.parseInt(each));
			}
		  }
		}
		List<DbAutoInterfacescenedetailsWithBLOBs> obj = (List<DbAutoInterfacescenedetailsWithBLOBs>) JSON.parseArray(dataitems, DbAutoInterfacescenedetailsWithBLOBs.class);
			try {
				result = caseMgmtV2Service.updateAutoCase(id,inf, env, url, inftype, degree, module, tester, reqType,
							outerparams, dataAsUrlparam, obj, ids);
			} catch (Exception e) {
					// TODO Auto-generated catch block
				e.printStackTrace();
			}
		if (result >= 0) {
			return JsonDataResult.ok();
		} else {
			return JsonDataResult.error(0);
		}
	}
	
	
	@RequestMapping(value = "/launchInterDetails.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult searchInterDetails(int summaryId, String levels) {
		List<Integer> levellist = new ArrayList<Integer>();
		if (!levels.isEmpty()) {
			String []ss = levels.split(",");
			List<String> levelss = Arrays.asList(ss);		
			for (String s : levelss) {
				levellist.add(Integer.parseInt(s));
			}
		}	
		List<DbAutoInterfacescenedetailsWithBLOBs> results = caseMgmtV2Service.getInfDetialsBySummary(summaryId,levellist);
		if(null != results){
			return JsonDataResult.ok(results);
		}
		return JsonDataResult.error(0);
	}
	
	@RequestMapping(value = "/loadSummById.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult loadSummById(int id) {
		List<DbAutoInterfacesummaryWithBLOBs> results = caseMgmtV2Service.loadSummById(id);
		if(null != results){
			return JsonDataResult.ok(results);
		}
		return JsonDataResult.error(0);
	}
	
	@RequestMapping(value = "/loadDetailBySummaryId.action", method = {
			RequestMethod.POST }, produces = "application/json; charset=utf-8")
	@ResponseBody
	public JsonDataResult loadDetailBySummaryId(int id) {
		List<DbAutoInterfacescenedetailsWithBLOBs> results = caseMgmtV2Service.loadDetailBySummaryId(id);
		if(null != results){
			return JsonDataResult.ok(results);
		}
		return JsonDataResult.error(0);
	}

	private void init(HttpServletResponse response, String fileName) throws UnsupportedEncodingException {
		response.reset();
		response.setCharacterEncoding("GBK");
		response.setHeader("Content-disposition",
				"attachment;filename=" + new String(fileName.getBytes("GBK"), "iso8859-1"));
		response.setContentType("application/oct-stream");
	}

	private void write(SFTPOPBean result, HttpServletResponse response) {
		PrintWriter output = null;
		InputStream in = null;
		try {
			if ((in = result.getIn()) != null) {
				output = response.getWriter();
				String str;
				char[] b = new char[1024];
				BufferedReader inReader = new BufferedReader(new InputStreamReader(in));
				while ((str = inReader.readLine()) != null) {
					output.print(str);
					output.println();
				}
				output.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (in != null)
					in.close();
				if (output != null)
					output.close();
				closeChannel(result.getSftp());
				closeChannel(result.getChannel());
				closeSession(result.getSshSession());
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	private void closeChannel(Channel channel) {
		if (channel != null) {
			if (channel.isConnected()) {
				channel.disconnect();
			}
		}
	}

	private void closeSession(Session session) {
		if (session != null) {
			if (session.isConnected()) {
				session.disconnect();
			}
		}
	}
}
